package com.lkdont.android.media.opengl

import android.opengl.GLES20
import android.opengl.GLException

/**
 * OpenGL程序
 *
 * @author lqd
 */
abstract class GLProgram(
    private val vertexShader: GLShader,
    private val fragmentShader: GLShader
) {

    /*** 程序句柄 */
    private var programHandle: Int = create()

    /*** OpenGL程序句柄 */
    val handle: Int
        get() {
            if (programHandle == 0) {
                throw GLException(0, "Could not get released program.")
            }
            return programHandle
        }

    /**
     * 创建OpenGL程序
     *
     * @return 程序句柄
     */
    private fun create(): Int {
        val vertexShaderHandle = vertexShader.handle
        val fragmentShaderHandle = fragmentShader.handle
        // 创建程序
        val program = GLES20.glCreateProgram()
        Utils.checkGLError("glCreateProgram")
        // 链接着色器
        GLES20.glAttachShader(program, vertexShaderHandle)
        Utils.checkGLError("glAttachShader")
        GLES20.glAttachShader(program, fragmentShaderHandle)
        Utils.checkGLError("glAttachShader")
        GLES20.glLinkProgram(program)
        // 检查链接状态
        val linkStatus = IntArray(1)
        GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0)
        if (linkStatus[0] != GLES20.GL_TRUE) {
            val errMsg = GLES20.glGetProgramInfoLog(program)
            // 释放程序
            GLES20.glDeleteProgram(program)
            throw GLException(linkStatus[0], "Could not link program: $errMsg")
        }
        return program
    }

    fun release() {
        if (programHandle != 0) {
            GLES20.glDeleteProgram(programHandle)
            programHandle = 0
        }
    }

    /*** 绘制 */
    abstract fun draw()

}